#pragma once
#include <string>
#include <vector>
#include <sstream>
#include <cstdarg>
#include <any>
#include <ctime>
#include <iomanip>
#include <stdexcept>
#include <algorithm>
#include <cmath>
#include <locale> // 用于数字千分位分隔（可选）
#include <yzrutil.h>
#include <util/Util.h>
#include <lang/StringFormat.hpp>

namespace yzrilyzr_util{
	class MessageFormat{
		private:
		struct FormatElement{
			yzrilyzr_lang::String literal="";       // 普通文本
			u_index index=-1;            // 参数索引
			yzrilyzr_lang::String formatType="";    // 格式类型 (number, date, time等)
			yzrilyzr_lang::String formatStyle="";   // 格式样式（内置风格如currency，或自定义模式如#.##）
			bool isArgument=false;   // 是否为参数
		};

		// ========================= 新增：数字模式解析与格式化 =========================
		// 解析数字模式（如#.##），提取整数部分、小数部分长度、是否显示千分位
		struct NumberPatternInfo{
			int integerMinDigits=1;  // 整数部分最小位数（默认1，避免0显示为空）
			int integerMaxDigits=-1; // 整数部分最大位数（-1表示无限制）
			int fractionMinDigits=0; // 小数部分最小位数
			int fractionMaxDigits=0; // 小数部分最大位数
			bool useThousands=false; // 是否显示千分位（如#,###.##）
			bool isPercent=false;    // 是否为百分比（模式含%）
			bool isCurrency=false;   // 是否为货币（模式含$，可选）
		};

		// 解析自定义数字模式（如#.##、#,###.00、#%）
		static NumberPatternInfo parseNumberPattern(const yzrilyzr_lang::String & pattern1){
			NumberPatternInfo info;
			std::string integerPart;  // 模式的整数部分（.之前）
			std::string fractionPart; // 模式的小数部分（.之后）
			bool inFraction=false;  // 是否进入小数部分
			std::string pattern=pattern1.tostring();
			for(char c:pattern){
				if(c == '.'){
					inFraction=true;
					continue;
				}
				if(c == ','){
					info.useThousands=true;
					continue;
				}
				if(c == '%'){
					info.isPercent=true;
					continue;
				}
				if(c == '$'){
					info.isCurrency=true;
					continue;
				}
				// 处理数字占位符（#：可选位，0：必占位）
				if(inFraction){
					fractionPart+=c;
				} else{
					integerPart+=c;
				}
			}

			// 解析整数部分：计算最小/最大位数
			if(!integerPart.empty()){
				int required=0; // 0的个数（必占位）
				int optional=0; // #的个数（可选位）
				for(char c:integerPart){
					if(c == '0') required++;
					else if(c == '#') optional++;
				}
				info.integerMinDigits=required;
				info.integerMaxDigits=(optional == 0 && required == 0)?-1:(required + optional);
			}

			// 解析小数部分：计算最小/最大位数
			if(!fractionPart.empty()){
				int required=0;
				int optional=0;
				for(char c:fractionPart){
					if(c == '0') required++;
					else if(c == '#') optional++;
				}
				info.fractionMinDigits=required;
				info.fractionMaxDigits=required + optional;
			}

			return info;
		}

		// 按自定义模式格式化数字（核心函数）
		static std::string formatNumberByPattern(double number, const NumberPatternInfo & info){
			std::stringstream ss;
			// 处理百分比：数值×100
			if(info.isPercent){
				number*=100;
			}

			// 1. 设置小数精度（最小≤显示位数≤最大）
			ss << std::fixed;
			int aaa=static_cast<int>(std::ceil(-std::log10(std::fabs(std::modf(number, &number)) + 1e-9)));
			int precision=Util::clamp(aaa, info.fractionMinDigits, info.fractionMaxDigits);
			ss << std::setprecision(precision);

			// 2. 处理千分位分隔（可选，依赖locale）
			if(info.useThousands){
				ss.imbue(std::locale("en_US.UTF-8")); // 英文locale支持千分位逗号
			}

			// 3. 输出数字（整数部分自动补0或截断，小数部分按精度显示）
			ss << number;

			// 4. 处理货币符号（可选，默认前缀$，可扩展为其他货币）
			std::string result=ss.str();
			if(info.isCurrency){
				result="$" + result;
			}

			// 5. 处理百分比符号（后缀）
			if(info.isPercent){
				result+="%";
			}

			return result;
		}

		// ========================= 原有功能：解析格式字符串 =========================
		static std::vector<FormatElement> parse(const yzrilyzr_lang::String & pattern){
			std::vector<FormatElement> elements;
			u_index pos=0;
			const u_index len=pattern.length();

			while(pos < len){
				u_index start=pattern.indexOf('{', pos);
				if(start == -1){
					elements.push_back({pattern.substring(pos), -1, "", "", false});
					break;
				}
				if(start > pos){
					elements.push_back({pattern.substring(pos, start), -1, "", "", false});
				}

				u_index end=pattern.indexOf('}', start + 1);
				if(end == -1){
					elements.push_back({pattern.substring(start), -1, "", "", false});
					pos=len;
					break;
				}

				// 解析参数部分（格式：index,type,style/pattern）
				yzrilyzr_lang::String argPart=pattern.substring(start + 1, end);
				FormatElement elem;
				elem.isArgument=true;

				// 分割：index,type,style（支持逗号分隔，如{0,number,#.##}）
				std::vector<std::string> parts;
				u_index comma1=argPart.indexOf(',');
				u_index comma2=(comma1 != -1)?argPart.indexOf(',', comma1 + 1):-1;

				if(comma1 == -1){
					// 仅索引（如{0}）
					try{
						elem.index=std::stoi(argPart.tostring());
					} catch(...){
						elements.push_back({pattern.substring(start, end), -1, "", "", false});
						pos=end + 1;
						continue;
					}
				} else{
					// 索引 + 类型 + 风格/模式（如{0,number,#.##}）
					yzrilyzr_lang::String indexStr=argPart.substring(0, comma1);
					try{
						elem.index=std::stoi(indexStr.tostring());
					} catch(...){
						elements.push_back({pattern.substring(start, end), -1, "", "", false});
						pos=end + 1;
						continue;
					}
					elem.formatType=argPart.substring(comma1 + 1, (comma2 != -1)?comma2:argPart.length());
					if(comma2 != -1){
						elem.formatStyle=argPart.substring(comma2 + 1);
					}
				}

				elements.push_back(elem);
				pos=end + 1;
			}
			return elements;
		}

		// ========================= 原有功能：内置风格格式化（兼容） =========================
		static std::string formatNumber(double number, const yzrilyzr_lang::String & style){
			// 先检查是否为自定义模式（含#或0），优先用模式格式化
			if(style.indexOf('#') != -1 || style.indexOf('0') != -1){
				NumberPatternInfo info=parseNumberPattern(style);
				return formatNumberByPattern(number, info);
			}

			// 原有内置风格（currency/percent等）
			std::stringstream ss;
			if(style == "integer"){
				ss << static_cast<long>(number);
			} else if(style == "currency"){
				ss.imbue(std::locale("en_US.UTF-8"));
				ss << std::fixed << std::setprecision(2) << "$" << number;
			} else if(style == "percent"){
				ss << std::fixed << std::setprecision(2) << (number * 100) << "%";
			} else if(style == "short"){
				ss << std::fixed << std::setprecision(0) << number;
			} else if(style == "long"){
				ss << std::fixed << std::setprecision(3) << number;
			} else{
				ss << number;
			}
			return ss.str();
		}

		// ========================= 原有功能：日期/时间格式化 =========================
		static std::string formatDate(time_t date, const yzrilyzr_lang::String & style){
			std::stringstream ss;
			struct tm & timeinfo=*localtime(&date);
			if(style == "short"){
				ss << std::setfill('0') << std::setw(2) << (timeinfo.tm_mon + 1) << "/"
					<< std::setw(2) << timeinfo.tm_mday << "/"
					<< std::setw(2) << (timeinfo.tm_year % 100);
			} else if(style == "medium"){
				static const char * months[]={"Jan", "Feb", "Mar", "Apr", "May", "Jun",
					"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
				ss << months[timeinfo.tm_mon] << " " << std::setw(2) << timeinfo.tm_mday << ", "
					<< (timeinfo.tm_year + 1900);
			} else if(style == "long"){
				static const char * longMonths[]={"January", "February", "March", "April", "May", "June",
					"July", "August", "September", "October", "November", "December"};
				ss << longMonths[timeinfo.tm_mon] << " " << std::setw(2) << timeinfo.tm_mday << ", "
					<< (timeinfo.tm_year + 1900);
			} else{
				ss << std::put_time(&timeinfo, "%Y-%m-%d");
			}
			return ss.str();
		}

		static std::string formatTime(time_t time, const yzrilyzr_lang::String & style){
			std::stringstream ss;
			struct tm & timeinfo=*localtime(&time);
			if(style == "short"){
				ss << std::put_time(&timeinfo, "%I:%M %p");
			} else if(style == "medium"){
				ss << std::put_time(&timeinfo, "%I:%M:%S %p");
			} else{
				ss << std::put_time(&timeinfo, "%H:%M:%S");
			}
			return ss.str();
		}

		// ========================= 原有功能：参数包转vector =========================
		static void fillArgs(std::vector<std::any> & args){}

		template<typename T, typename... Rest>
		static void fillArgs(std::vector<std::any> & args, const T & first, const Rest&... rest){
			args.push_back(first);
			fillArgs(args, rest...);
		}

		public:
			// ========================= 格式化入口（兼容原有调用） =========================
		template<typename... Args>
		static yzrilyzr_lang::String format(const yzrilyzr_lang::String & pattern, const Args&... args){
			std::vector<yzrilyzr_lang::String> arguments11={yzrilyzr_lang::ObjectUtil::toString(args)...};
			std::vector<FormatElement> elements=parse(pattern);
			std::vector<std::any> arguments;
			fillArgs(arguments, args...);

			std::stringstream result;
			for(const auto & elem : elements){
				if(!elem.isArgument){
					result << elem.literal;
					continue;
				}

				// 检查索引有效性
				if(elem.index < 0 || elem.index >= arguments.size()){
					result << "{" << elem.index << "}";
					continue;
				}

				try{
					const std::any & arg=arguments[elem.index];
					// 处理数字类型（优先自定义模式，再内置风格）
					if(elem.formatType == "number"){
						double num=0;
						// 支持int/long/float/double等数字类型
						if(arg.type() == typeid(int)) num=std::any_cast<int>(arg);
						else if(arg.type() == typeid(long)) num=std::any_cast<long>(arg);
						else if(arg.type() == typeid(float)) num=std::any_cast<float>(arg);
						else if(arg.type() == typeid(double)) num=std::any_cast<double>(arg);
						else if(arg.type() == typeid(int32_t)) num=std::any_cast<int32_t>(arg);
						else if(arg.type() == typeid(int64_t)) num=std::any_cast<int64_t>(arg);
						else if(arg.type() == typeid(uint32_t)) num=std::any_cast<uint32_t>(arg);
						else if(arg.type() == typeid(uint64_t)) num=std::any_cast<uint64_t>(arg);
						else if(arg.type() == typeid(u_index)) num=std::any_cast<u_index>(arg);
						else{
							result << "{invalid number type}";
							continue;
						}
						// 调用格式化（自动识别模式/风格）
						result << formatNumber(num, elem.formatStyle);
					}
					// 原有日期/时间处理
					else if(elem.formatType == "date" && arg.type() == typeid(time_t)){
						result << formatDate(std::any_cast<time_t>(arg), elem.formatStyle);
					} else if(elem.formatType == "time" && arg.type() == typeid(time_t)){
						result << formatTime(std::any_cast<time_t>(arg), elem.formatStyle);
					}
					// 无格式或其他类型
					else{
						if(arg.type() == typeid(std::string)) result << std::any_cast<std::string>(arg);
						else if(arg.type() == typeid(int32_t)) result << std::any_cast<int32_t>(arg);
						else if(arg.type() == typeid(float)) result << std::any_cast<float>(arg);
						else if(arg.type() == typeid(double)) result << std::any_cast<double>(arg);
						else if(arg.type() == typeid(int64_t)) result << std::any_cast<int64_t>(arg);
						else{
							if(!arg.has_value()){
								result << "empty";
							} else{
								result << arguments11[elem.index];
							}
						}
					}
				} catch(const std::bad_any_cast &){
					result << "{type mismatch}";
				} catch(...){
					result << "{error formatting}";
				}
			}
			return result.str();
		}
	};
} // namespace yzrilyzr_util